#ifndef BUFFER_H
#define BUFFER_H

#include <assert.h>
#include <atomic>
#include <cstddef>
#include <cstring>
#include <iostream>
#include <string>
#include <sys/uio.h>
#include <unistd.h>
#include <vector>
#include <string.h>

class Buffer {
public:
  // 缓冲区大小为1024字节
  Buffer(int initBuffSize = 1024);
  ~Buffer() = default;

  // 这个size_t可能是为了和vector的类型对应
  size_t WritableBytes() const;
  size_t ReadableBytes() const;
  size_t PrependableBytes() const; // 可预置字节数量？不是很明白

  const char *Peek() const;         // 当前读指针的位置
  void EnsureWriteable(size_t len); // 确保有足够的字节来写数据
  void HasWritten(size_t len);

  void Retrieve(size_t len); // 从缓冲区中读取len字节数据
  void RetrieveUntil(const char *end); // 从缓冲区读取数据直到遇到了end标识符

  void RetrieveAll();             // 读取缓冲区中的所有数据
  std::string RetrieveAllToStr(); // 读取所有数据并转换为std::string

  const char *BeginWriteConst() const; // 用于查看当前读指针的位置
  char *BeginWrite();                  // 向缓冲区中写数据？

  // 将不同类型的数据加到缓冲区尾部
  void Append(const std::string &str);
  void Append(const char *str, size_t len);
  void Append(const void *data, size_t len);
  void Append(const Buffer &buff);

  /*
    因为涉及了系统函数的调用
    系统函数在调用后会通过设置errno来表明该系统调用是否调用成功
    只是我还不是很明白为什么这里需要手动传入这个int* Errno
    难道不能直接使用errno吗
  */
  ssize_t ReadFD(int fd, int* Errno);
  ssize_t WriteFD(int fd, int* Errno);

private:
  char* BeginPtr_();
  const char* BeginPtr_() const;
  void MakeSpace_(size_t len); // 对缓冲区的大小进行修改，当其剩余空间不足以对数据进行写入的时候就需要调用

  std::vector<char> buffer_;
  // atomic的使用有点忘了（
  std::atomic<std::size_t> readPos_;
  std::atomic<std::size_t> writePos_;
};

#endif // BUFFER_H